#include <iostream>
#include <vector>

#include "point_in_polygon.hpp"

static void test_1(void)
{
    const std::vector<Point> points = {
        Point(120.76058685779572, 30.754246669718142),
        Point(120.76067805290222, 30.754232839681332),
        Point(120.76089799404143, 30.754237449693825),
        Point(120.76110720634462, 30.754274329785837),
        Point(120.76141297817229, 30.754389579982387),
        Point(120.76143980026245, 30.75452327003756),
        Point(120.76131105422974, 30.754707669809072),
        Point(120.76119840145111, 30.754786039605044),
        Point(120.76104283332825, 30.754859799354733),
        Point(120.76086044311522, 30.754905899169604),
        Point(120.76066195964815, 30.75489206922747),
        Point(120.7604044675827, 30.754864409337227),
        Point(120.76022744178772, 30.75476759965879),
        Point(120.76018989086151, 30.75461546996746),
        Point(120.76016843318938, 30.754417240009037),
        Point(120.76029181480406, 30.754260499752995),
        Point(120.76058685779572, 30.754246669718142),
        Point(120.76058685779572, 30.754246669718142),
    };
    const auto lineString = LineString(points);
    const std::vector<LineString> lines = {lineString};
    const auto polygon = Polygon(lines);

    const auto point = Point(120.76072023855993, 30.754585451323287);

    const auto in = polygon.containsPoint(point, false);

    std::cout << "test_1: " << in << std::endl;
}

static void test_2(void)
{
    const std::vector<Point> points = {
        Point(0, 0),
        Point(1, 0),
        Point(1, 1),
        Point(1, 1),
    };
    const auto lineString = LineString(points);
    const std::vector<LineString> lines = {lineString};
    const auto polygon = Polygon(lines);

    const auto point = Point(0.5, 0.5);

    const auto in = polygon.containsPoint(point, false);

    std::cout << "test_1: " << in << std::endl;
}

static void test_3(void)
{
    const std::vector<Point> points = {
        Point(0, 0),
        Point(1, 0),
        Point(1, 1),
        Point(1, 1),
    };
    const auto lineString = LineString(points);
    const std::vector<LineString> lines = {lineString};
    const auto polygon = Polygon(lines);

    const auto point = Point(1.5, 0.5);

    const auto in = polygon.containsPoint(point, false);

    std::cout << "test_3: " << in << std::endl;
}

static void test_4(void)
{
    const std::vector<Point> points = {
        {
            -86.70478820800781,
            36.23084281427824,
        },
        {
            -86.73980712890625,
            36.21062368007896,
        },
        {
            -86.71371459960938,
            36.173495506147,
        },
        {
            -86.67526245117186,
            36.17709826419592,
        },
        {
            -86.67303085327148,
            36.20910010895552,
        },
        {
            -86.68041229248047,
            36.230427405208005,
        },
        {
            -86.70478820800781,
            36.23084281427824,
        },
    };
    const auto lineString = LineString(points);
    const std::vector<LineString> lines = {lineString};
    const auto polygon = Polygon(lines);

    const auto point = Point(-86.72229766845702, 36.20258997094334);

    const auto in = polygon.containsPoint(point, false);

    std::cout << "test_4: " << in << std::endl;
}

int main(int argc, char *argv[])
{
    test_1();
    test_2();
    test_3();
    test_4();
}
